﻿using System;
using System.Collections;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using NHDay_Linq.Domain;
using NHibernate;
using NHibernate.Linq;
using NHibernate.Tool.hbm2ddl;
using NUnit.Framework;

namespace NHDay_Linq
{
	[TestFixture]
	public class T03_UnsupportedArrayQueriesTests : TestBase
	{
		[TestFixtureSetUp]
		public void FixtureSetup()
		{
			CreateDatabase();
		}

		[TearDown]
		public void TearDown()
		{
			using (ISession session = SessionFactory.OpenSession())
			{
				session.Clear();
			}
		}

		[Test]
		public void T01_QueryWithArray_Ints()
		{
			using (ISession session = SessionFactory.OpenSession())
			using (ITransaction tx = session.BeginTransaction())
			{

				int[] arr = new int[] {People[0].Id, -1, -2};
				var magnus = session.Query<Person>().Where(t => arr.Contains(t.Id)).FirstOrDefault();
				
				Assert.IsNotNull(magnus);
				Assert.AreEqual("Magnus", magnus.FirstName);

				tx.Commit();
			}
		}

		[Test]
		public void T02_QueryWithList_Ints()
		{
			using (ISession session = SessionFactory.OpenSession())
			using (ITransaction tx = session.BeginTransaction())
			{

				List<int> list = new List<int>() {People[0].Id, -1, -2};
				var magnus = session.Query<Person>().Where(t => list.Contains(t.Id)).FirstOrDefault();

				Assert.IsNotNull(magnus);
				Assert.AreEqual("Magnus", magnus.FirstName);

				tx.Commit();
			}
		}

		[Test]
		public void T03_QueryWithList_IEnumerableInts()
		{
			using (ISession session = SessionFactory.OpenSession())
			using (ITransaction tx = session.BeginTransaction())
			{

				IEnumerable<int> list = new List<int>() { People[0].Id, -1, -2 };
				var magnus = session.Query<Person>().Where(t => list.Contains(t.Id)).FirstOrDefault();

				Assert.IsNotNull(magnus);
				Assert.AreEqual("Magnus", magnus.FirstName);

				tx.Commit();
			}
		}

		[Test]
		public void T04_QueryWithList_IListInts()
		{
			using (ISession session = SessionFactory.OpenSession())
			using (ITransaction tx = session.BeginTransaction())
			{

				IList<int> list = new List<int>() { People[0].Id, -1, -2 };
				var magnus = session.Query<Person>().Where(t => list.Contains(t.Id)).FirstOrDefault();

				Assert.IsNotNull(magnus);
				Assert.AreEqual("Magnus", magnus.FirstName);

				tx.Commit();
			}
		}

		[Test]
		public void T05_QueryWithList_IListInts_Workaround()
		{
			using (ISession session = SessionFactory.OpenSession())
			using (ITransaction tx = session.BeginTransaction())
			{

				IList<int> list = new List<int>() { People[0].Id, -1, -2 };
				var magnus = session.Query<Person>().Where(t => ((IEnumerable<int>)list).Contains(t.Id)).FirstOrDefault();

				Assert.IsNotNull(magnus);
				Assert.AreEqual("Magnus", magnus.FirstName);

				tx.Commit();
			}
		}

		[Test]
		public void T06_QueryWithArray_Person()
		{
			using (ISession session = SessionFactory.OpenSession())
			using (ITransaction tx = session.BeginTransaction())
			{
				Adult[] relatives = new Adult[] { (Adult)People[0], (Adult)People[3] };

				var ronny = session.Query<Child>().Where(t => relatives.Contains(t.Father)).FirstOrDefault();

				Assert.IsNotNull(ronny);
				Assert.AreEqual("Ronny", ronny.FirstName);

				tx.Commit();
			}
		}

		[Test]
		public void T07_QueryWithList_IEnumerablePerson()
		{
			using (ISession session = SessionFactory.OpenSession())
			using (ITransaction tx = session.BeginTransaction())
			{
				IEnumerable<Adult> relatives = new List<Adult>() { (Adult)People[0], (Adult)People[3] };
				
				var ronny = session.Query<Child>().Where(t => relatives.Contains(t.Father)).FirstOrDefault();

				Assert.IsNotNull(ronny);
				Assert.AreEqual("Ronny", ronny.FirstName);

				tx.Commit();
			}
		}

		[Test]
		public void T08_QueryWithList_ListPerson()
		{
			using (ISession session = SessionFactory.OpenSession())
			using (ITransaction tx = session.BeginTransaction())
			{
				List<Adult> relatives = new List<Adult>() { (Adult)People[0], (Adult)People[3] };

				var ronny = session.Query<Child>().Where(t => relatives.Contains(t.Father)).FirstOrDefault();

				Assert.IsNotNull(ronny);
				Assert.AreEqual("Ronny", ronny.FirstName);

				tx.Commit();
			}
		}

		[Test]
		public void T09_QueryWithList_IListPerson()
		{
			using (ISession session = SessionFactory.OpenSession())
			using (ITransaction tx = session.BeginTransaction())
			{
				IList<Adult> relatives = new List<Adult>() { (Adult)People[0], (Adult)People[3] };

				var ronny = session.Query<Child>().Where(t => relatives.Contains(t.Father)).FirstOrDefault();

				Assert.IsNotNull(ronny);
				Assert.AreEqual("Ronny", ronny.FirstName);

				tx.Commit();
			}
		}

		[Test]
		public void T10_QueryWithList_IListPerson_Workaround()
		{
			using (ISession session = SessionFactory.OpenSession())
			using (ITransaction tx = session.BeginTransaction())
			{
				IList<Adult> relatives = new List<Adult>() { (Adult)People[0], (Adult)People[3] };

				var ronny = session.Query<Child>().Where(t => ((IEnumerable<Adult>)relatives).Contains(t.Father)).FirstOrDefault();

				Assert.IsNotNull(ronny);
				Assert.AreEqual("Ronny", ronny.FirstName);

				tx.Commit();
			}
		}
	}
}
